package com.tanhua.dubbo.huanxin.api.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.dubbo.api.HuanXinApi;
import com.tanhua.dubbo.enums.HuanXinMessageType;
import com.tanhua.dubbo.huanxin.config.HuanXinConfig;
import com.tanhua.dubbo.huanxin.mapper.HuanXinUserMapper;
import com.tanhua.dubbo.huanxin.service.RequestService;
import com.tanhua.dubbo.huanxin.service.TokenService;
import com.tanhua.dubbo.pojo.HuanXinUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@DubboService(version = "1.0.0")
@Slf4j
public class HuanXinApiImpl implements HuanXinApi {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private RequestService requestService;

    @Autowired
    private HuanXinConfig huanXinConfig;

    @Autowired
    private HuanXinUserMapper huanXinUserMapper;

    @Override
    public String getToken() {
        return this.tokenService.getToken();
    }

    @Override
    public Boolean register(Long userId) {
        ///{org_name}/{app_name}/users
        String url = StrUtil.format("{}/{}/{}/users",
                this.huanXinConfig.getUrl(),
                this.huanXinConfig.getOrgName(),
                this.huanXinConfig.getAppName());

        Map<String, String> param = new HashMap<>();
        param.put("username", "HX_" + userId);
        param.put("password", IdUtil.simpleUUID());
        param.put("nickname", "HX_" + userId);

        String json = JSONUtil.toJsonStr(param);
        boolean isOk = this.requestService.execute(url, json, Method.POST).isOk();
        if (isOk) {
            //保存数据到MySQL
            HuanXinUser huanXinUser = new HuanXinUser();
            huanXinUser.setUserId(userId);
            huanXinUser.setUsername(param.get("username"));
            huanXinUser.setPassword(param.get("password"));
            huanXinUser.setCreated(new Date());
            huanXinUser.setUpdated(huanXinUser.getCreated());
            huanXinUser.setNickname(huanXinUser.getUsername());
            return this.huanXinUserMapper.insert(huanXinUser) == 1;
        } else {
            // 如果失败，需要删除环信中的用户
            this.delete(userId, json);
        }
        return false;
    }

    /**
     * 删除环信用户
     *
     * @param userId
     * @return
     */
    @Override
    public Boolean delete(Long userId, String json) {
        //	/{org_name}/{app_name}/users/{username}
        String url = StrUtil.format("{}/{}/{}/users/{}",
                this.huanXinConfig.getUrl(),
                this.huanXinConfig.getOrgName(),
                this.huanXinConfig.getAppName(),
                Convert.toStr("HX_" + userId));
        //删除环信中的用户
        boolean isOk = this.requestService.execute(url, json, Method.DELETE).isOk();
        if (isOk) {
            //删除mongodb中的环信用户
            QueryWrapper<HuanXinUser> wrapper = new QueryWrapper<>();
            wrapper.eq("username", Convert.toStr("HX_" + userId));
            return this.huanXinUserMapper.delete(wrapper) == 1;
        }
        return false;
    }

    @Override
    public HuanXinUser queryHuanXinUser(Long userId) {
        QueryWrapper<HuanXinUser> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        return this.huanXinUserMapper.selectOne(wrapper);
    }

    @Override
    public HuanXinUser queryUserByUserName(String userName) {
        QueryWrapper<HuanXinUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", userName);
        return this.huanXinUserMapper.selectOne(wrapper);
    }

    @Override
    public Boolean addUserFriend(Long userId, Long friendId) {
        ///{org_name}/{app_name}/users/{owner_username}/contacts/users/{friend_username}
        String url = StrUtil.format("{}/{}/{}/users/{}/contacts/users/{}",
                this.huanXinConfig.getUrl(),
                this.huanXinConfig.getOrgName(),
                this.huanXinConfig.getAppName(),
                "HX_" + userId,
                "HX_" + friendId);

        HttpResponse response = this.requestService.execute(url, null, Method.POST);
        if (response.isOk()) {
            return true;
        }

        if (response.getStatus() == 404) {
            log.error("添加好友关系到环信失败，IM用户不存在 userId = {}, friendId = {}", userId, friendId);
        }
        return false;
    }

    @Override
    public Boolean removeUserFriend(Long userId, Long friendId) {
        ///{org_name}/{app_name}/users/{owner_username}/contacts/users/{friend_username}
        String url = StrUtil.format("{}/{}/{}/users/{}/contacts/users/{}",
                this.huanXinConfig.getUrl(),
                this.huanXinConfig.getOrgName(),
                this.huanXinConfig.getAppName(),
                "HX_" + userId,
                "HX_" + friendId);

        HttpResponse response = this.requestService.execute(url, null, Method.DELETE);
        if (response.isOk()) {
            return true;
        }

        if (response.getStatus() == 404) {
            log.error("删除环信的好友关系失败，IM用户不存在 userId = {}, friendId = {}", userId, friendId);
        }
        return false;
    }

    @Override
    public Boolean sendMsgFromAdmin(String targetUserName, HuanXinMessageType huanXinMessageType,
                                    String msg) {
        // //{org_name}/{app_name}/messages
        String url = StrUtil.format("{}/{}/{}/messages",
                this.huanXinConfig.getUrl(),
                this.huanXinConfig.getOrgName(),
                this.huanXinConfig.getAppName());

        Map<String, Object> map = new HashMap<>();
        map.put("target_type", "users");
        map.put("target", Arrays.asList(targetUserName));

        Map<String, Object> msgMap = new HashMap<>();
        msgMap.put("type", huanXinMessageType.getType());
        msgMap.put("msg", msg);

        map.put("msg", msgMap);
        map.put("from", "admin");

        HttpResponse response = this.requestService.execute(url, JSONUtil.toJsonStr(map), Method.POST);
        if (response.isOk()) {
            return true;
        }

        if (response.getStatus() == 400) {
            log.error("发送给环信的消息结构有误！ userName = {}, msg = {}", targetUserName, msg);
        }
        return false;
    }
}
